<?php
namespace app\controller;

use think\Request;
use think\facade\Db;
use think\facade\Env;
use think\helper\Str;
use app\model\Bazaar;
use OSS\OssClient;
use OSS\Core\OssException;
use \wapmorgan\UnifiedArchive\UnifiedArchive;

class TemplateEditor extends Common
{

	/**
	* 清空文件目录
	*
	* @return
	*/
	function delete_directory($dirname) {
				 if (is_dir($dirname))
					 $dir_handle = opendir($dirname);
		 if (!$dir_handle)
					return false;
		 while($file = readdir($dir_handle)) {
					 if ($file != "." && $file != "..") {
								if (!is_dir($dirname."/".$file))
										 unlink($dirname."/".$file);
								else
										 $this->delete_directory($dirname.'/'.$file);
					 }
		 }
		 closedir($dir_handle);
		 rmdir($dirname);
		 return true;
	}

	/**
	 * 编译模板
	 *
	 * @return
	 */
	private function compile($request, $file, $config) {
		$contents = @file_get_contents($file);
		if(!$contents) {
			return false;
		}
		$contentArray = explode('</body>', $contents);
		$contentText = $contentArray [0];
		$contentText .= '<!--[if !IE]>|xCode00|' . time() . '<![endif]-->' . "\n";
		$contentText .= '<script type="text/javascript">
(function() {
	var createCloud = document.createElement("script");
	createCloud.id = "san_cloud";
	createCloud.setAttribute("sid", "'.$request->sessInfo['companyId'].'");
	createCloud.src = "https://api.jiafen520.com/cloud/san_cloud.js";
	var createAgl = document.getElementsByTagName("script")[0];
	createAgl.parentNode.insertBefore(createCloud, createAgl);
})();
</script>' . "\n" ;
		$contentText = str_replace('contenteditable="true"', 'data-contenteditable', $contentText);
		$contentText = str_replace( '【性别标签】', '<span class="app_sex"></span>', $contentText);
		$contentText = str_replace( '【微信昵称】', '<span class="app_name"></span>', $contentText);
		$contentText = str_replace( '【二维码标签】', '<img class="app_qrcode"></img>', $contentText);
		$contentText = str_replace( '【手机号标签】', '<span class="app_phone"></span>', $contentText);
		$contentText = str_replace( '【微信标签】', '<span class="app_wechat" style="color: #ff0000;"></span>', $contentText);
		$contentText .= $config['BaiduCode'] . "\n";
		$contentText .= "</body>" . "\n";
		$contentText .= "</html>" . "\n";
		file_put_contents($file, $contentText);
		return true;
	}

	/**
	 * 查询数据
	 *
	 * @return
	 */
	public function read(Request $request) {
		if($this->hasPermission($request->sessInfo, 'templateeditor:read')) {
			return ['code'=> 403, 'msg'=> '你没有权限执行此操作!'];;
		}

		$where = [];
		$limit = $request->param('limit/d', 20);
		$sort = $request->param('sort', 'id', 'trim');
		$order = $request->param('order', 'desc', 'trim');

		array_push( $where, ['companyId', '=', $request->sessInfo['companyId'] ] );

		$SiteName = $request->param('SiteName', '', 'trim');
		if($SiteName) {
			array_push( $where, ['SiteName', 'like',  "%{$SiteName}%" ] );
		}

		$DomainUrl = $request->param('DomainUrl', '', 'trim');
		if($DomainUrl) {
			array_push( $where, ['DomainUrl', 'like',  "%{$DomainUrl}%" ] );
		}

		$bazaar = $request->param('bazaar', '', 'trim');
		if($bazaar) {
			array_push( $where, ['bazaar', '=',  $bazaar ] );
		}

		$static = public_path('static');
		if( is_dir($static ) ) {
			$this->deleteExpireTemplate($static);
		}

		$query = Db::name('cfg_site')->where($where)->order($sort, $order)->paginate($limit);
		$items = $query->items();
		foreach($items as &$value ) {
			if($value['SiteSource']) {
				$value['issource'] = file_exists(public_path('storage')  . 'templates' . DIRECTORY_SEPARATOR . $value['SiteSource']);
			} else {
				$value['issource'] = false;
			}
		}

		return ['code'=> 0, 'msg'=> '', 'count'=> $query->total(), 'data'=> $items, 'bazaar' => Bazaar::getList($request->sessInfo)];
	}

	/**
	 * 删除2小时之前模板
	 *
	 * @return
	 */
	public function deleteExpireTemplate($dir) {
		$opendir = opendir($dir);
		if( $opendir ) {
			while(false !== ( $file = readdir($opendir)) ) {
				if (( $file != '.' ) && ( $file != '..' )) {
					$fileName = $dir . $file;
					if ( file_exists($fileName) ) {
						$filectime = filectime ($fileName);
						if( $filectime < (time() - ( 120 * 60)) ) {
							@chmod($fileName, 0777);
							@unlink($fileName);
						}
					}
				}
			}
			closedir($opendir);
		}
	}

	/**
	 * 站点重置
	 *
	 * @return
	 */
	public function resetTemplate(Request $request) {
		if($this->hasPermission($request->sessInfo, 'templateeditor:save')) {
			return ['code'=> 403, 'msg'=> '你没有权限执行此操作!'];;
		}

		$id = $request->param('id', '', 'trim');
		if(empty($id)) {
			return ['code'=>403, 'msg'=>'站点ID异常, 操作失败!'];
		}

		$site = Db::table('cfg_site')->where('companyId', $request->sessInfo['companyId'])->where('id', $id)->find();
		if(!isset($site['id'])){
			return ['code'=>403, 'msg'=>'落地页不存在, 操作失败!'];
		}

		if(empty($site['url'])) {
			return ['code'=>403, 'msg'=>'站点URL未配置, 操作失败!'];
		}

		if(empty($site['Domains'])) {
			return ['code'=>403, 'msg'=>'绑定域名未配置, 操作失败!'];
		}

		if(empty($site['btAddress'])) {
			return ['code'=>403, 'msg'=>'宝塔WebHook未配置, 操作失败!'];
		}

		if(empty($site['btKey'])) {
			return ['code'=>403, 'msg'=>'宝塔WebHook密匙未配置, 操作失败!'];
		}

		if(empty($site['aPage'])) {
			return ['code'=>403, 'msg'=>'站点目录未配置, 操作失败!'];
		}

		if(empty($site['SiteSource'])) {
			return ['code'=>403, 'msg'=>'站点源码未上传, 操作失败!'];
		}

		if( substr_count($site['aPage'], '/') < 3 ) {
			return ['code'=>403, 'msg'=>'站点目录不合法 操作失败<br>系统检测到当前站点目录'.$site['aPage'].'<br>请确保确保网站目录在"/www/wwwroot/域名/真网站目录"'];
		}

		$storagePath = public_path('storage');
		if( !is_dir($storagePath) ) {
			mkdir($storagePath, 0777, true);
		}

		$sourcePath = $storagePath  . 'source' . DIRECTORY_SEPARATOR . $site['SiteSource'];
		if(!file_exists($sourcePath)) {
			return ['code'=>403, 'msg'=>'站点源码未上传, 操作失败!'];
		}

		$zipFileName = md5($request->sessInfo['companyId'] . $site['DomainUrl']);
		$unpackPath = $storagePath  . 'edit' . DIRECTORY_SEPARATOR . $zipFileName;
		if(is_dir($unpackPath)) {
			$this->delete_directory($unpackPath);
		}

		$archive = UnifiedArchive::open($sourcePath);
		if( !$archive ) {
			return ['code'=>403, 'msg'=>'模板初始化失败, 操作失败!'];
		}

		if(!is_array($archive->getFileNames())) {
			return ['code'=>403, 'msg'=>'模板初始化失败, 操作失败!'];
		}

		$filesNumber = $archive->extractFiles($unpackPath);
		if( $filesNumber  == 0) {
			return ['code'=>403, 'msg'=>'模板解压失败, 操作失败!'];
		}

		$indexFile = $unpackPath . DIRECTORY_SEPARATOR . 'index.html';
		if(!file_exists($indexFile)) {
			return ['code'=>403, 'msg'=>'模板已损坏, 操作失败!'];
		}

		$content = $this->compile($request, $indexFile, $site);
		if(!$content) {
			return ['code'=>403, 'msg'=>'模板编译失败, 操作失败!'];
		}

        $saveFileName = md5( $zipFileName . date('YmdHis')) . '.zip';
        $saveDirectory = public_path('static') . $saveFileName;
		$archiveDirectory = UnifiedArchive::archiveDirectory($unpackPath, $saveDirectory);
		if( !$archiveDirectory ) {
			return ['code'=>403, 'msg'=>'模板打包失败, 操作失败!'];
		}

		$downloadUrl = 'https://api.jiafen520.com/static/' . $saveFileName;
		$result = doGetRequest($site['btAddress'].'hook?access_key='.$site['btKey'].'&param=setTemplate;' .$site['aPage'] . ';' . $downloadUrl);
		if(empty($result)){
			return ['code'=>403, 'msg'=>'网络通信异常, 操作失败!'];
		}

		$datacode = json_decode($result, true);
		if(!isset($datacode['code'])) {
			return ['code'=>403, 'msg'=>'网络通信异常, 操作失败!'];
		}

		if( $datacode['code'] == 0) {
			return ['code'=>403, 'msg'=>'宝塔KEY密匙错误, 操作失败!'];
		}

		Db::name('cfg_site')->where('id', $site['id'])->update(['editDate' => date('Y-m-d H:i:s')]);

		return ['code'=>0, 'msg'=>'站点模板重置指令发送成功.<br>具体是否操作成功, 请查看操作日志.<br>如果提示成功预计生效时间1-10分钟生效。'];
	}

	/**
	 * 站点重置结果
	 *
	 * @return
	 */
	public function resetTemplateLog(Request $request) {
		if($this->hasPermission($request->sessInfo, 'templateeditor:save')) {
			return ['code'=> 403, 'msg'=> '你没有权限执行此操作!'];;
		}
		$id = $request->param('id', '', 'trim');
		if(empty($id)) {
			return ['code'=>403, 'msg'=>'站点ID异常, 操作失败!'];
		}
		$site = Db::table('cfg_site')->where('companyId', $request->sessInfo['companyId'])->where('id', $id)->find();
		if(!isset($site['id'])){
			return ['code'=>403, 'msg'=>'落地页不存在, 操作失败!'];
		}
		$data = doGetRequest($site['url'] . '/mm-template.log');
		return ['code'=>0, 'msg'=> $data ];
	}

	/**
	 * 查询模板
	 *
	 * @return
	 */
	public function defaultExists(Request $request) {
		if($this->hasPermission($request->sessInfo, 'templateeditor:save')) {
			return ['code'=> 403, 'msg'=> '你没有权限执行此操作!'];;
		}
		$id = $request->param('id', '', 'trim');
		$source = $request->param('SiteSource', 'desc', 'trim');
		if(empty($id)) {
			return ['code'=>403, 'msg'=>'站点ID异常, 操作失败!'];
		}
		if(empty($source)) {
			return ['code'=>403, 'msg'=>'模板不存在, 操作失败!'];
		}
		if(!file_exists(public_path('storage')  . 'source' . DIRECTORY_SEPARATOR . $source)){
			return ['code'=>403, 'msg'=>'模板不存在, 操作失败!'];
		}
		return ['code'=>0, 'msg'=>''];
	}

	/**
	 * 预编译模板
	 *
	 * @return
	 */
	public function compileTemplate(Request $request) {
		if($this->hasPermission($request->sessInfo, 'templateeditor:save')) {
			return ['code'=> 403, 'msg'=> '你没有权限执行此操作!'];;
		}
		$id = $request->param('id', '', 'trim');
		if(empty($id)) {
			return ['code'=>403, 'msg'=>'站点ID异常, 操作失败!'];
		}
		$site = Db::table('cfg_site')->where('companyId', $request->sessInfo['companyId'])->where('id', $id)->find();
		if(!isset($site['id'])){
			return ['code'=>403, 'msg'=>'落地页不存在, 操作失败!'];
		}
		if(empty($site['SiteSource'])) {
			return ['code'=>403, 'msg'=>'站点源码未上传, 操作失败!'];
		}
		
		$storageDirectory  = public_path('storage');
		$compileFilename = md5($request->sessInfo['companyId'] . $site['DomainUrl']);
		$compileDirectory = $storageDirectory . 'edit' . DIRECTORY_SEPARATOR . $compileFilename;
		$compileNewIndex = $compileDirectory . DIRECTORY_SEPARATOR . md5('index') . '.html';
		$compileOldIndex = $compileDirectory . DIRECTORY_SEPARATOR . 'index.html';
		if(!file_exists($compileOldIndex)) {
			return ['code'=>403, 'msg'=>'模板已损坏, 操作失败!'];
		}

		$editHtml = $request->param('editHtml', '', 'urldecode');
		if(!$editHtml){
		   	return ['code'=>403, 'msg'=>'模版数据异常, 操作失败!'];
		}

    	$contentArray = explode('<!--[if !IE]>|xCode00|', $editHtml);
    	$contentText = $contentArray [0];
    	$contentText = str_replace('style="position: relative;"', '', $contentText);
    	$contentText = str_replace('contenteditable="true"', 'data-contenteditable', $contentText);

		$compilehead = '';
		$compileText = file_get_contents($compileOldIndex);
		if(strripos($compileText, "<body>") === false) {
            $compileTemp = preg_split("/<body ([\s\S]*?)>/", $compileText, null, PREG_SPLIT_DELIM_CAPTURE);
            $compilehead = $compileTemp[0] . "<body {$compileTemp[1]}>";
		} else {
		    $compileTemp = explode('<body>', $compileText);
		    $compilehead = $compileTemp[0] . "<body>";
		}
		
		$compileHtml = $compilehead . $contentText;
		$compileHtml .= '<!--[if !IE]>|xCode00|' . time() . '<![endif]-->' . "\n";
		$compileHtml .= '<script type="text/javascript">
(function() {
	var createCloud = document.createElement("script");
	createCloud.id = "san_cloud";
	createCloud.setAttribute("sid", "'.$request->sessInfo['companyId'].'");
	createCloud.src = "https://api.jiafen520.com/cloud/san_cloud.js";
	var createAgl = document.getElementsByTagName("script")[0];
	createAgl.parentNode.insertBefore(createCloud, createAgl);
})();
</script>' . "\n" ;

		$compileHtml = str_replace('contenteditable="true"', 'data-contenteditable', $compileHtml);
		$compileHtml = str_replace( '【性别标签】', '<span class="app_sex"></span>', $compileHtml);
		$compileHtml = str_replace( '【微信昵称】', '<span class="app_name"></span>', $compileHtml);
		$compileHtml = str_replace( '【二维码标签】', '<img class="app_qrcode"></img>', $compileHtml);
		$compileHtml = str_replace( '【手机号标签】', '<span class="app_phone"></span>', $compileHtml);
		$compileHtml = str_replace( '【微信标签】', '<span class="app_wechat" style="color: #ff0000;"></span>', $compileHtml);
		$compileHtml .= $site['BaiduCode'] . "\n";
		$compileHtml .= "</body>" . "\n";
		$compileHtml .= "</html>" . "\n";
		file_put_contents($compileOldIndex, $compileHtml);
		return ['code'=>0, 'msg'=>'模板预编译成功!'];
	}


	/**
	 * 初始化编辑
	 *
	 * @return
	 */
	public function editExists(Request $request) {
		if($this->hasPermission($request->sessInfo, 'templateeditor:save')) {
			return ['code'=> 403, 'msg'=> '你没有权限执行此操作!'];;
		}
		
		$id = $request->param('id', '', 'trim');
		if(empty($id)) {
			return ['code'=>403, 'msg'=>'站点ID异常, 操作失败!'];
		}

		$site = Db::table('cfg_site')->where('companyId', $request->sessInfo['companyId'])->where('id', $id)->find();
		if(!isset($site['id'])){
			return ['code'=>403, 'msg'=>'落地页不存在, 操作失败!'];
		}
		if(empty($site['SiteSource'])) {
			return ['code'=>403, 'msg'=>'站点源码未上传, 操作失败!'];
		}
		
		$storageDirectory  = public_path('storage');
		$zipFilename = md5($request->sessInfo['companyId'] . $site['DomainUrl']);
		$htmlDirectory = $storageDirectory . 'edit' . DIRECTORY_SEPARATOR . $zipFilename;
		$indexDirectory = $htmlDirectory . DIRECTORY_SEPARATOR . 'index.html';
		if(!file_exists($indexDirectory)) {
			$sourcePath = $storageDirectory  . 'source' . DIRECTORY_SEPARATOR . $site['SiteSource'];
			if(!file_exists($sourcePath)) {
				return ['code'=>403, 'msg'=>'站点源码未上传, 操作失败!'];
			}
			$archive = UnifiedArchive::open($sourcePath);
			if( !$archive ) {
				return ['code'=>403, 'msg'=>'模板初始化失败, 操作失败!'];
			}
			if(!is_array($archive->getFileNames())) {
				return ['code'=>403, 'msg'=>'模板初始化失败, 操作失败!'];
			}
			$filesNumber = $archive->extractFiles($htmlDirectory);
			if( $filesNumber  == 0) {
				return ['code'=>403, 'msg'=>'模板解压失败, 操作失败!'];
			}
		}

		$contents = @file_get_contents($indexDirectory);
		if(!$contents) {
			return ['code'=>403, 'msg'=>'模板初始化失败, 操作失败!'];
		}

		if( stripos($contents, '<!--[if !IE]>|xCode00|') === false ) {
			$contentArray = explode('</body>', $contents);
		} else {
			$contentArray = explode('<!--[if !IE]>|xCode00|', $contents);
		}

		$contentText = $contentArray [0];
		$contentText = str_replace( '<span class="app_sex"></span>','【性别标签】', $contentText);
		$contentText = str_replace( '<span class="app_name"></span>', '【微信昵称】', $contentText);
		$contentText = str_replace( '<img class="app_qrcode"></img>', '【二维码标签】', $contentText);
		$contentText = str_replace( '<span class="app_phone"></span>', '【手机号标签】', $contentText);
		$contentText = str_replace( '<span class="app_wechat" style="color: #ff0000;"></span>', '【微信标签】', $contentText);
		$contentText = str_replace('data-contenteditable', 'contenteditable="true"', $contentText);
		$contentText .= '<!--[if !IE]>|xCode00|' . time() . '<![endif]-->' . "\n";
		$contentText .= '<script type="text/javascript" src="https://api.jiafen520.com/ckeditor/ckeditor.js"></script>' . "\n";
		$contentText .= "</body>" . "\n";
		$contentText .= "</html>" . "\n";
		$contentText = str_replace(["/r/n", "/r", "/n"], "", $contentText);
		@file_put_contents($indexDirectory, $contentText);
		return ['code'=>0, 'msg'=>'', 'url' => 'https://hzz.jiafen520.com/api/Browse?id='. $zipFilename ];
	}

	/**
	 * 站点模板编辑
	 *
	 * @return
	 */
	public function compileTemplates(Request $request) {
		if($this->hasPermission($request->sessInfo, 'templateeditor:save')) {
			return ['code'=> 403, 'msg'=> '你没有权限执行此操作!'];;
		}

		$id = $request->param('id', '', 'trim');
		if(empty($id)) {
			return ['code'=>403, 'msg'=>'站点ID异常, 操作失败!'];
		}

		$site = Db::table('cfg_site')->where('companyId', $request->sessInfo['companyId'])->where('id', $id)->find();
		if(!isset($site['id'])){
			return ['code'=>403, 'msg'=>'落地页不存在, 操作失败!'];
		}

		if(empty($site['url'])) {
			return ['code'=>403, 'msg'=>'站点URL未配置, 操作失败!'];
		}

		if(empty($site['Domains'])) {
			return ['code'=>403, 'msg'=>'绑定域名未配置, 操作失败!'];
		}

		if(empty($site['btAddress'])) {
			return ['code'=>403, 'msg'=>'宝塔WebHook未配置, 操作失败!'];
		}

		if(empty($site['btKey'])) {
			return ['code'=>403, 'msg'=>'宝塔WebHook密匙未配置, 操作失败!'];
		}

		if(empty($site['aPage'])) {
			return ['code'=>403, 'msg'=>'站点目录未配置, 操作失败!'];
		}

		if(empty($site['SiteSource'])) {
			return ['code'=>403, 'msg'=>'站点源码未上传, 操作失败!'];
		}

		if( substr_count($site['aPage'], '/') < 3 ) {
			return ['code'=>403, 'msg'=>'站点目录不合法 操作失败<br>系统检测到当前站点目录'.$site['aPage'].'<br>请确保确保网站目录在"/www/wwwroot/域名/真网站目录"'];
		}

		$zipFileName = md5($request->sessInfo['companyId'] . $site['DomainUrl']);
		$saveFilePath = md5( $zipFileName . date('YmdHis')) . '.zip';
		$saveDirectory = public_path('storage') . 'edit'. DIRECTORY_SEPARATOR . $zipFileName;
		$zipDirectory  = public_path('static') . $saveFilePath;
		if(!is_dir($saveDirectory)) {
			return ['code'=>403, 'msg'=>'站点目录不存在, 操作失败!'];
		}

		$archiveDirectory = UnifiedArchive::archiveDirectory($saveDirectory, $zipDirectory);
		if(!$archiveDirectory) {
			return ['code'=>403, 'msg'=>'创建ZIP文件失败, 操作失败!'];
		}

		$downloadUrl = 'https://api.jiafen520.com/static/' . $saveFilePath;
		$result = doGetRequest($site['btAddress'].'hook?access_key='.$site['btKey'].'&param=setTemplate;' .$site['aPage'] . ';' . $downloadUrl);
		if(empty($result)){
			return ['code'=>403, 'msg'=>'网络通信异常, 操作失败!'];
		}

		$datacode = json_decode($result, true);
		if(!isset($datacode['code'])) {
			return ['code'=>403, 'msg'=>'网络通信异常, 操作失败!'];
		}

		if( $datacode['code'] == 0) {
			return ['code'=>403, 'msg'=>'宝塔KEY密匙错误, 操作失败!'];
		}

		Db::name('cfg_site')->where('id', $site['id'])->update(['editDate' => date('Y-m-d H:i:s')]);

		return ['code'=>0, 'msg'=>'站点模板编辑指令发送成功.<br>具体是否操作成功, 请查看操作日志.<br>如果提示成功预计生效时间1-10分钟生效。'];
	}


}
